/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package facade.mrp;

import businessData.Bool;
import businessData.CustomerPlan;
import businessData.Distribution;
import businessData.DistributionPlan;
import businessData.MasterPlan;
import businessData.MyFloat;
import businessData.Nodo;
import businessData.Order;
import businessData.SnapShot;
import entities.Material;
import entities.Product;
import entities.ProductStructure;
import entities.SupplierXproduct;
import entities.SupplierXproductPK;
import entities.SupplierXpyme;
import facade.MaterialFacadeRemote;
import facade.NonWorkingDayFacadeRemote;
import facade.ProductFacadeRemote;
import facade.SupplierFacadeRemote;
import facade.SupplierXproductFacadeRemote;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Stateless;

/**
 *
 * @author PabloSebastian
 */
@Stateless
@Remote(MRPFacadeRemote.class)
public class MRPFacade implements MRPFacadeRemote {
    
    private List<Order> productionOrders;
    
    @EJB
    ProductFacadeRemote productFacade;
    @EJB
    private MaterialFacadeRemote materialFacade;
    @EJB
    private SupplierXproductFacadeRemote supplierProductFacade ;
    @EJB
    private SupplierFacadeRemote supplierFacade;
    @EJB
    private NonWorkingDayFacadeRemote nonWorkinkDayFacade;
    private Integer majorDayAll = 0;
    Integer tag =0;
    
    public MRPFacade() {
        //System.out.println("Entro constructora de MRPFacade...");
        File file2 = new File("MRPProductionOrders.dat");
        if(!file2.exists()) {
            //System.out.println("No existe archivo de datos MRPProductionOrders! se creará una nueva lista...");
            productionOrders = new ArrayList<>();
        }
        else {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(file2);
                ObjectInputStream ois = new ObjectInputStream(fis);
                productionOrders = (List<Order>)ois.readObject();
                //System.out.println("Existe archivo de datos MRPProductionOrders.dat! Tam Lista: " + productionOrders.size());
            } catch (IOException | ClassNotFoundException ex) {
                productionOrders = new ArrayList<>();
            }
        }
    }
    
    @Override
    public MasterPlan ProductsPlan(List<List<String>> pedido, int pymeId) {
              
        MasterPlan myMasterPlan = new MasterPlan();
        List<List<Order>> Allordes = new ArrayList<>();
        DistributionPlan myDistributionPlan = new DistributionPlan();
        ArrayList<Distribution> distributionList = new ArrayList<>();
        int endIteratorOrder = pedido.size();
        for (int iteratorOrder = 0; iteratorOrder < endIteratorOrder; iteratorOrder++) //rof1  
        {
            ArrayList<Order> CustomerList = new ArrayList<>();
            boolean isDad = true;//trash
            Distribution dist = new Distribution();
            Integer Dad = Integer.parseInt(pedido.get(iteratorOrder).get(0));
            float quantityRequest = Float.parseFloat(pedido.get(iteratorOrder).get(1));
            Product newproduct = productFacade.find(Dad);
            float inventory = Float.valueOf(String.valueOf(newproduct.getQuantity())) - quantityRequest;
            dist.setId(newproduct.getIdproduct());
            dist.setName(newproduct.getName());
            if(inventory >= 0) {
                dist.setQuantityInventory(quantityRequest);
                dist.setQuantityProduction(0);
            }
            else{
                dist.setQuantityInventory(Float.parseFloat(String.valueOf(newproduct.getQuantity())));
                dist.setQuantityProduction(Math.abs(inventory));
            }
            distributionList.add(dist);
            SnapShot productShot = new SnapShot(Dad, Float.valueOf(String.valueOf(newproduct.getHowmanythisday())), newproduct.getProductionabledate(), Float.valueOf(String.valueOf(newproduct.getQuantity())));
            CreateShots(Dad, myMasterPlan);
            Float quantity = Float.parseFloat(pedido.get(iteratorOrder).get(1));
            calculatingOrdersOneProduct(Dad, quantity, Allordes, CustomerList, isDad, pymeId);
            float sumProduction = 0;
            String nameProduct = null;
            int iterator = 0;
            int endIterator = Allordes.size();
            for (int i = 0; i < endIterator; i++)//rof3 
            {
                List<Order> orderlist = Allordes.get(i);
                for (Order order : orderlist) //rof4 
                {
                    if (order.isInventary()) {
                        myMasterPlan.addChildMyStockPlan(order);
                        if (order.getId() == Dad) {
                            
                            //System.out.println("order inventary " + order.isInventary());
                            myMasterPlan.addChildMyCustomerPlan(order);      
                        }
                    }
                    if (order.getDestine() == (Integer) 1) {
                        if (order.getId() != Dad) {
                            myMasterPlan.addChildMyProductionPlan(order);
                        }
                        if (order.getId() == Dad) {
                            //System.out.println("__________________CustomerList_________________" + CustomerList.size());
                            tag++;
                            if (tag == CustomerList.size()) {
                                for (Order orderc : CustomerList) {
                                    float newQ = 0;
                                    if (newproduct.getCapacity() < orderc.getQuantity()) {
                                        newQ = Float.valueOf(String.valueOf(newproduct.getCapacity()));
                                    } else {
                                        newQ = order.getQuantity();
                                    }
                                    Order ordercopy = new Order(orderc.getId(), orderc.getQuantity(), orderc.getDate(), orderc.getName(), orderc.getIdDad());
                                    ordercopy.setInventary(false);
                                    //System.out.println("ordercopy " + ordercopy.getQuantity() + " getDate " + ordercopy.getDate() + " getQuantity() " + ordercopy.getQuantity());
                                    myMasterPlan.addChildMyCustomerPlan(ordercopy);
                                    Order ordercopy2 = new Order(orderc.getId(), orderc.getQuantity(), orderc.getDate(), orderc.getName(), orderc.getIdDad());
                                    Date firstDate = addDaysToDate(ordercopy2.getDate(), -(int) (newproduct.getProductiontime()));
                                    ordercopy2.setDate(firstDate);
                                    myMasterPlan.addChildMyProductionPlan(ordercopy2);
                                }
                            }
                        }

                    }
                    if (order.getDestine() == (Integer) 2) {
                        myMasterPlan.addChildMySupplyPlan(order);
                    }
                }//rof4 
            }//rof3 
            Allordes.clear();
        }//rof1
        showMasterPlan(myMasterPlan);
        //System.out.println("---------------------------------------------- ---- MRP");
        tag = 0; 
        majorDayAll = 0;
        
        myMasterPlan = addNonWorkinkDay(myMasterPlan , 1, pymeId);
        if (!myMasterPlan.getMyProductionPlan().getProductionPlanList().isEmpty())
        {
            myMasterPlan = addNonWorkinkDay(myMasterPlan , 2, pymeId);
            myMasterPlan = addNonWorkinkDay(myMasterPlan , 3, pymeId);
        }
        
        myDistributionPlan.setMyDistributionList(distributionList);
        myMasterPlan.setMydistributionPlan(myDistributionPlan);
        return myMasterPlan;
    }

 
    
    public void CreateShots(Integer Dad, MasterPlan myMasterPlan ) 
    {
       Product newproduct = productFacade.find(Dad);
       SnapShot productShot = new SnapShot(Dad, Float.valueOf(String.valueOf(newproduct.getHowmanythisday())),Float.valueOf(String.valueOf(newproduct.getQuantity())), newproduct.getProductionabledate());
       myMasterPlan.AddShot(productShot);
       boolean  answer = doYouHaveChildren(Dad);
        if (answer == true) {
            List<ProductStructure> structures = newproduct.getProductStructureList();
            for (ProductStructure tProductstructure : structures) {       
                Integer MySon = tProductstructure.getProduct1().getIdproduct();
                Float quantityRequired = Float.valueOf(String.valueOf(tProductstructure.getQuantityrequired()));
                CreateShots(MySon, myMasterPlan) ;          
            }
        }
    }

    private boolean doYouHaveChildren(Integer Dad) 
    {
        Product newproduct;
        newproduct = productFacade.find(Dad);
        if (!newproduct.getProductStructureList().isEmpty()) {
            return true;
        }
        return false;
    }
    
    public void calculatingOrdersOneProduct(Integer Dad, Float quantity, List<List<Order>> Allordes, List<Order> CustomerList, boolean isDad,int pymeId) 
    {

        Product newp = productFacade.find(Dad);
        productFacade.edit(newp);
        //productFacade.refresh(newp);
        //productFacade.flush();
        List<Order> MyOrders = new ArrayList<>();
        majorDayAll = 0;
        Integer quantityProduct = 0;
        List<Order> allMyOrders = new ArrayList<>();
        Nodo Tree = CreateTree(Dad, (float) quantityProduct, allMyOrders, majorDayAll);
        Date dateEnd = dateFinish(Dad, majorDayAll);
        //System.out.println("//////////////////////7");
        if (newp.getQuantity() >= quantity) {
            //System.out.println(" newp.getQuantity() >= quantity ");   
            Order order = new Order(Dad);
            order.setIdDad(Dad);
            order.setName(newp.getName());
            order.setInventary(true);
            Date today= new Date();//new 15-12
            order.setDate(today);//new 15-12
            //System.out.println("dateOrder1 "+order.getDate());       
            order.setQuantityInventary(quantity);
            MyOrders.add(order);
            Allordes.add(MyOrders);
            Float Quantityfalse = (float) 0;
            Order CustomerOrder = new Order(Dad, Quantityfalse, order.getDate(), newp.getName(), Dad);
            CustomerList.add(CustomerOrder);
            Product newp1 = productFacade.find(Dad);
            Float setQ = Float.valueOf(String.valueOf(newp.getQuantity())) - quantity;
            newp1.setQuantity(setQ);
            productFacade.edit(newp1);              
            return;
        }

        float howMany = Float.valueOf(String.valueOf(newp.getHowmanythisday()));
        float capacity = Float.valueOf(String.valueOf(newp.getCapacity()));
        float QuantityInventary = Float.valueOf(String.valueOf(newp.getQuantity()));
        float myRealCapacity = (capacity * howMany) + QuantityInventary;
        float remainder = (myRealCapacity) - quantity;
        //System.out.println("remainder "+remainder);
        //System.out.println("capacity "+capacity);
        //System.out.println("howMany "+howMany);
        //System.out.println("myRealCapacity "+myRealCapacity);
        //System.out.println("QuantityInventary "+QuantityInventary);
        //System.out.println("quantity "+quantity);
        if (remainder == 0) {       
            //System.out.println("remainder == 0");
            mrp(dateEnd, MyOrders, Dad, quantity, Dad, pymeId);
            Date newAble = orderTheOrders(MyOrders, dateEnd);
            newp.setProductionabledate(newAble);
            showOrder(MyOrders);
            Allordes.add(MyOrders);
            newp.setHowmanythisday((float) 1);
            if (isDad == true) {
                Order CustomerOrder = new Order(Dad, (capacity * howMany), newAble, newp.getName(), Dad);
                CustomerList.add(CustomerOrder);
            }
            return;
        }
        if (remainder > 0) 
        {        
            //System.out.println(" remainder > 0 ");
            mrp(dateEnd, MyOrders, Dad, quantity, Dad, pymeId);
            Date newAble = orderTheOrders(MyOrders, dateEnd);  
            //System.out.println("newAble " + newAble);
            //System.out.println(" capacity "+capacity);
            newp.setProductionabledate(newAble);
            showOrder(MyOrders);
            Allordes.add(MyOrders);
            float newHowMany = remainder / capacity;
            newp.setHowmanythisday(newHowMany);
            if (isDad == true) {
               Order CustomerOrder = new Order(Dad, quantity-QuantityInventary, newAble, newp.getName(), Dad);
               MyOrders.add(CustomerOrder);
               CustomerList.add(CustomerOrder);
            }
            return;
        }
        if (remainder < 0) 
        {   
            //System.out.println("remainder < 0 ");
            Product newproduct = productFacade.find(Dad);
            float Inventory = Float.valueOf(String.valueOf(newproduct.getQuantity()));
            float totalCapacity = myRealCapacity;
            {
                mrp(dateEnd, MyOrders, Dad, totalCapacity, Dad, pymeId);
                Date newAble = orderTheOrders(MyOrders, dateEnd);
                Product newp2 = productFacade.find(Dad);
                //System.out.println("holaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
                productFacade.edit(newp2);
                //productFacade.refresh(newp2);
                //productFacade.flush();
                newp2.setProductionabledate(newAble);
                Allordes.add(MyOrders);
                newp2.setHowmanythisday((float) 1);
                if (isDad == true) {
                    //System.out.println("isDad Dad "+Dad+" myRealCapacity "+myRealCapacity+" newAble "+newAble+" newp.getName() " +newp.getName()+" capacity "+capacity); 
                    Order CustomerOrder = new Order(Dad, capacity*howMany, newAble, newp.getName(), Dad);
                    //System.out.println("CustomerOrder.getQuantity() "+CustomerOrder.getQuantity());
                    CustomerList.add(CustomerOrder);
                }
               
                productFacade.edit(newp2);
                //productFacade.refresh(newp2);
                //productFacade.flush();
                calculatingOrdersOneProduct(Dad, Math.abs(remainder), Allordes, CustomerList, true, pymeId);
            }

        }
        
    }
    
    public Nodo CreateTree(Integer Dad, Float quantityProduct, List<Order> allMyOrders, Integer majorDay) 
    {
        Nodo Newleaf = new Nodo();
        Newleaf.setId(Dad);
        boolean answer;
        answer = doYouHaveChildren(Dad);
        Product newproduct;
        newproduct = productFacade.find(Dad);
        if (answer) {
            majorDay = majorDay + (int) newproduct.getProductiontime();
        } else {
            int timeResponse = newproduct.getSupplierXproductList().get(0).getResponsetime();
            majorDay = majorDay + timeResponse;
        }
        if (answer == true) {
            List<ProductStructure> structures = newproduct.getProductStructureList();
            for (ProductStructure tProductstructure : structures) {
                Nodo NewLeafSon;
                Integer MySon = tProductstructure.getProduct1().getIdproduct();
                Float quantityRequired = Float.valueOf(String.valueOf(tProductstructure.getQuantityrequired()));
                Float newQuantityRequired = quantityProduct * quantityRequired;
                NewLeafSon = CreateTree(MySon, newQuantityRequired, allMyOrders, majorDay);
                NewLeafSon.setQuantity(quantityRequired);
                Newleaf.addChild(NewLeafSon);
            }
        } else {
            if (majorDay > majorDayAll) {
                majorDayAll = majorDay;
            }
        }
        return Newleaf;
    }
    
    public Date dateFinish(Integer Dad, Integer timeMake) {
        Product newproduct = productFacade.find(Dad);
        Date AbleDate = newproduct.getProductionabledate();
        Date today= new Date();
        
        if (today.before(AbleDate) || today.equals(AbleDate)) {
            AbleDate = addDaysToDate(AbleDate, timeMake);
            return AbleDate;
        } else {
            today = addDaysToDate(today, timeMake);
            return today;
        }
    }
    
    public static Date addDaysToDate(Date date, int days) {
        return addMinutesToDate(date, 60 * 24 * days);
    }
    
    public static Date addMinutesToDate(Date date, int minutes) {
        Calendar calendarDate = Calendar.getInstance();
        calendarDate.setTime(date);
        calendarDate.add(Calendar.MINUTE, minutes);
        return calendarDate.getTime();
    }
    
    public void mrp(Date dateEnd, List<Order> MyOrders, Integer Dad, Float quantityProduct, Integer finalDad , int pymeId) 
    {
        Product newproduct = productFacade.find(Dad);    
        String email = "";
        String  typeMaterial = ""; 
        if (newproduct.getMaterial() != null)
        {
             typeMaterial = newproduct.getMaterial().getTypematerial();
        }
        boolean answer = doYouHaveChildren(Dad);
        Integer wait = 0;
        if (answer) {
            wait = (int) newproduct.getProductiontime();
        } else {
            Material material = materialFacade.find(typeMaterial);
            List<SupplierXpyme> supplierXmaterial = material.getSupplierXpymeList();
            for (int i  = 0; i < supplierXmaterial.size(); i++)
            {
                SupplierXpyme sxp = supplierXmaterial.get(i);
                //System.out.println("estoy eligiendo el correo -------------------------- :)");
                if (sxp.getSupplierXpymePK().getPymeidentification() == pymeId)
                {
                    //System.out.println("identificacion del proveedor  --> " + sxp.getSupplierXpymePK().getSupplierindentification());
                    //System.out.println("identificacion del producto  --> " + newproduct.getIdproduct());
                    SupplierXproduct supplierProduct = new SupplierXproduct(sxp.getSupplierXpymePK().getSupplierindentification(), newproduct.getIdproduct());
                    supplierProduct = supplierProductFacade.find(supplierProduct.getSupplierXproductPK());
                    
                    wait = supplierProduct.getResponsetime();
                    //System.out.println("waiittttttttttttttttt   " + wait);
                    email = supplierProduct.getSupplier().getEmail();
                    i = supplierXmaterial.size();
                    //System.out.println("voy a imprimir el email elegido ------>   " + email);
                }
            }
        }
        Date result = addDaysToDate(dateEnd, -wait);
        Bool make = new Bool();
        make.setMake(true); 
        MyFloat QuantityInventary = new MyFloat((float) 0);
        Float quantityProduct2 = updateInventory(quantityProduct, Dad, make, QuantityInventary,dateEnd);
        //System.out.println("quantityProduct2    "+quantityProduct2+" Dad "+Dad);
        Order order = new Order(Dad, quantityProduct2, result, newproduct.getName(), finalDad);
        order.setIdDad(finalDad);
        order.setSupplierEmail(email);
        if (QuantityInventary.getInteger() > 0)
        {
            order.setInventary(true);
            Date today= new Date();//new 15-12
            order.setDate(today);//new 15-12
            order.setQuantityInventary(QuantityInventary.getInteger());  
        }

        if (quantityProduct2 == 0) 
        {
            order.setDestine(3);
        }
        MyOrders.add(order);
        if (make.getMake() == true)
        {
            
            List<ProductStructure> structures = newproduct.getProductStructureList();
            if (structures.isEmpty())
            {
                order.setDestine(2);
            } else {
                order.setDestine(1);
            }

            for (ProductStructure tProductstructure : structures) 
            {
                Integer MySon = tProductstructure.getProduct1().getIdproduct();
                Float quantityRequired = Float.valueOf(String.valueOf(tProductstructure.getQuantityrequired()));
                Float newQuantityRequired = quantityProduct2 * quantityRequired;
                mrp(result, MyOrders, MySon, newQuantityRequired, finalDad, pymeId);
            }
        }  
    }
    private Float updateInventory(Float quantityProduct, Integer Dad, Bool make, MyFloat QuantityInventary, Date dateEnd) 
    {

        Product newp = productFacade.find(Dad);
        float Inventory = Float.valueOf(String.valueOf(newp.getQuantity()));

        if (Inventory == 0) {
            newp.setProductionabledate(dateEnd);
            productFacade.flush();
            return quantityProduct;
        }
        float newQuantityProduct = quantityProduct - Inventory;
        if (newQuantityProduct == 0) {
            QuantityInventary.setInteger(quantityProduct);
            newp.setQuantity(0);
            newp.setProductionabledate(dateEnd);
            productFacade.edit(newp);//
            productFacade.flush();
            make.setMake(false);
            return (float) 0;
        }
        if (newQuantityProduct > 0) {
            QuantityInventary.setInteger(Inventory);
            newp.setQuantity(0);
            newp.setProductionabledate(dateEnd);
            productFacade.edit(newp);
            productFacade.flush();
            return newQuantityProduct;
        }

        QuantityInventary.setInteger(quantityProduct);
        newp.setQuantity((int) Math.abs(newQuantityProduct));
        newp.setProductionabledate(dateEnd);
        productFacade.edit(newp);
        productFacade.flush();
        make.setMake(false);
        return (float) 0;
    }
    
    public Date orderTheOrders(List<Order> MyOrders, Date dateEnd) {
       
        Date firstDate;
        firstDate = new Date(3222 - 1900, 10, 29);
        for (Order order : MyOrders) {
                if (order.getDate().before(firstDate)) {
                      firstDate = order.getDate();
            }
        }
        Date result = addDaysToDate(dateEnd, -majorDayAll);
        if (result.equals(firstDate)) {
            return dateEnd;
        } else 
        {
            int cont = 0;
            for (int i = 1; i < majorDayAll; i++) {
                Date temporal = result;
                if (addDaysToDate(temporal, i).equals(firstDate)) {
                           cont = i;
                }
            }
            showOrder(MyOrders);
            for (Order order : MyOrders) {
                Date dateTemporal = order.getDate();
                Date dateTemporal2 = addDaysToDate(dateTemporal, -cont);
                order.setDate(dateTemporal2);
            }

            Date newDateAble;
            newDateAble = addDaysToDate(dateEnd, -cont);
            return newDateAble;
        }
    }
    public void showOrder(List<Order> allMyOrders) {
               for (Order order : allMyOrders) {
            //System.out.println("Id " + order.getId() + " Qtotal " + order.getQuantityTotal() + " | - Q " + order.getQuantity() + " (1pro/2apro/3Inve) " + order.getDestine() + " |Qinventary " + order.getQuantityInventary() + " | Date " + order.getDate() + " | final Dad " + order.getIdDad()+ " order.isInventary() " +order.isInventary());
        }
    }   
    private void showMasterPlan(MasterPlan myMasterPlan) 
    {
        System.out.println("showMasterPlan");
        CustomerPlan mycustomerPlan = myMasterPlan.getMyCustomerPlan();
        List<Order> mycustomerPlanList = mycustomerPlan.getProductionPlanList();
        System.out.println("customerPlan");
        //System.out.println("size " + mycustomerPlanList.size());
        for (Order order : mycustomerPlanList) {
            if (order.isInventary()) {
                //System.out.println("Inventary");
                //System.out.println(" " + order.getName() + " | " + order.getQuantityInventary() + " | " + order.getId() + " | " + order.getDate());
            } else if (!(order.isInventary())) {
                //System.out.println("production");
                //System.out.println(" " + order.getName() + " | " + order.getQuantity() + " | " + order.getId() + " | " + order.getDate() + "  QuantityInventary " + order.getQuantityInventary() + "QuantityTotal()  " + order.getQuantityTotal());
            }
        }
        //System.out.println("Distribution");
        DistributionPlan myDistributionPlan = myMasterPlan.getMydistributionPlan();
        for (Distribution distributionOrder : myDistributionPlan.getMyDistributionList()) {
            //System.out.println("" + distributionOrder.getId() + " | " + distributionOrder.getName() + " |Inventory " + distributionOrder.getQuantityInventory() + " |Production " + distributionOrder.getQuantityProduction());
        }
        //System.out.println("Production");

        for (Order order : myMasterPlan.getMyProductionPlan().getProductionPlanList()) {
            //System.out.println(" " + order.getId() + " | " + order.getName() + " | " + order.getQuantity() + " | " + order.getDate());
        }
        //System.out.println("Supply");
        for (Order order : myMasterPlan.getMySupplyPlan().getSupplyPlanList()) {
            //System.out.println(" " + order.getId() + " | " + order.getName() + " | " + order.getQuantity() + " | " + order.getDate() + " | " + order.getSupplierEmail());
        }
        //System.out.println(" Stock ");
        for (Order order : myMasterPlan.getMyStockPlan().getStockPlanList()) {
            //System.out.println(" " + order.getId() + " | " + order.getName() + " | " + order.getQuantityInventary() + " | " + order.getDate());
        }
        //System.out.println("SnapShots");
        for (SnapShot snapShot : myMasterPlan.allSnapshot) {
            //System.out.println(" |Id: " + snapShot.getId() + " |Howmany: " + snapShot.getHowmany() + " |DateAble: " + snapShot.getDateAble());
        }
    }
    
    private void saveProductionOrders() {
        File file = new File("MRPProductionOrders.dat");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream os = new ObjectOutputStream(fos);
            os.writeObject(productionOrders);
            //System.out.println("Se escribió el objeto MRPProductionOrders.dat. Tam Lista: " + productionOrders.size());
        } catch (Exception e) {}
    }

    @Override
    public List<List<String>> addProductionListOrders(List<List<String>> customerRequest, int pymeId)
    {
        for (List<String> list : customerRequest) {
            Order o = new Order();
            o.setPymeId(pymeId);
            o.setId(Integer.parseInt(list.get(0)));
            o.setQuantity(Float.parseFloat(list.get(1)));
            if(productionOrders.isEmpty()) {
                productionOrders.add(o);
            }
            else {
                boolean founded = false;
                for (int i = 0; i < productionOrders.size() && founded == false; i++) {
                    Order temp = productionOrders.get(i);
                    if(temp.getPymeId() == pymeId) {
                        int x = temp.getId();
                        int y = o.getId();
                        if(x == y) {
                            productionOrders.get(i).setQuantity(productionOrders.get(i).getQuantity() + o.getQuantity());
                            founded = true;
                        }
                    }
                }
                if(!founded) {
                    productionOrders.add(o);
                }
            }
        }
        return getRequestsToMRP(false, pymeId);
    }
    
    @Override
    public List<List<String>> getRequestsToMRP(boolean timer, int pymeId) {
        return getRequestsToMRPSynchronized(timer, pymeId);
    }
    
    private synchronized List<List<String>> getRequestsToMRPSynchronized(boolean timer, int pymeId) {
        //System.out.println("---------- PRODUCTION ORDERS: " + productionOrders.size());
        List<List<String>> requests = new ArrayList<>();
        for (Order order : productionOrders) {
            if(order.getPymeId() == pymeId) {
                Product product = productFacade.find(order.getId());
                List<String> request = new ArrayList<>();
                if(timer) {
                    request.add("" + order.getId());
                    request.add("" + order.getQuantity());
                    order.setQuantity((float)0);
                    requests.add(request);
                }
                else {
                    if(order.getQuantity() >= product.getCapacity()) {
                        request.add("" + order.getId());
                        request.add("" + order.getQuantity());
                        order.setQuantity((float)0);
                        requests.add(request);
                    }
                }
            }
        }
        for (int i = 0; i < productionOrders.size(); i++) {
            Order order = productionOrders.get(i);
            if(order.getPymeId() == pymeId) {
                if(order.getQuantity() == 0) {
                    productionOrders.remove(i);
                    i --;
                }
            }
        }
        saveProductionOrders();
        return requests;
    }
    
    @Override
    public List<List<Order>> combineSuppliersOrder(List<Order> sourceList) {
        List<List<Order>> mainList = new ArrayList<>();
        for (Order order : sourceList) {
            List<Order> supplierProducts = new ArrayList<>();
            boolean found = false;
            for (int i = 0; i < mainList.size() && found == false; i++) {
                List<Order> currentList = mainList.get(i);
                if(!currentList.isEmpty()) {
                    String email = currentList.get(0).getSupplierEmail();
                    if(order.getSupplierEmail().equals(email)) {
                        supplierProducts = currentList;
                        found = true;
                    }
                }
            }
            if(!found) {
                List<Order> newSourceList = new ArrayList<>();
                Order o = new Order();
                o.setId(order.getId());
                o.setSupplierEmail(order.getSupplierEmail());
                o.setQuantity(order.getQuantity());
                o.setName(order.getName());
                newSourceList.add(o);
                mainList.add(newSourceList);
            }
            else {
                found = false;
                for(int i = 0; i < supplierProducts.size() && found == false; i++) {
                    if(supplierProducts.get(i).getName().equals(order.getName())) {
                        supplierProducts.get(i).setQuantity(supplierProducts.get(i).getQuantity() + order.getQuantity());
                        found = true;
                    }
                }
                if(!found) {
                    Order o = new Order();
                    o.setId(order.getId());
                    o.setSupplierEmail(order.getSupplierEmail());
                    o.setQuantity(order.getQuantity());
                    o.setName(order.getName());
                    supplierProducts.add(o);
                    
                }
            }
        }
        return mainList;
    }

    @Override
    public List<List<String>> splitBatch(List<List<Order>> sourceList) {
        //System.out.println("--------------------------------- splitBacht----------------------");
        for (List<Order> Lorder : sourceList) {
            //System.out.println(Lorder.get(0).getSupplierEmail());
            for (Order order : Lorder) {
                //System.out.println(order.getName());
            } 
        }
        
        List<List<String>> mainList = new ArrayList<>();
        for (List<Order> list : sourceList) {
            int supplierId = supplierFacade.findIdByEmail(list.get(0).getSupplierEmail());
            for (Order order : list) {
                SupplierXproductPK sxpPK = new SupplierXproductPK(supplierId, order.getId());
                SupplierXproduct sxp = supplierProductFacade.find(sxpPK);
                int batch = sxp.getLote();
                int noBatches = (int)(order.getQuantity() / batch);
                float residue = order.getQuantity() % batch;
                int i = 1;
                for (i = 1; i <= noBatches; i++) {
                    List<String> orderString = new ArrayList<>();
                    orderString.add(order.getName());
                    //System.out.println("----------------> name:" + order.getName());
                    orderString.add("" + i);
                    orderString.add("" + batch);
                    orderString.add("" + batch);
                    orderString.add(order.getSupplierEmail());
                    mainList.add(orderString);
                }
                if(residue > 0) {
                    List<String> orderString = new ArrayList<>();
                    orderString.add(order.getName());
                    //System.out.println("----------------> name:" + order.getName());
                    orderString.add("" + i);
                    orderString.add("" + residue);
                    orderString.add("" + batch);
                    orderString.add(order.getSupplierEmail());
                    mainList.add(orderString);
                }
            }
        }
        
         //System.out.println("--------------------------------- splitBacht Despues----------------------");
      
         for (List<String> Lorder : mainList) {
            //System.out.println("paso a uno nuevo");
            for (String order : Lorder) {
                //System.out.println(order);
            } 
        }
        
        return mainList;
    }

    @Override
    public List<List<Order>> notifySuppliers(List<List<String>> sourceList) {
        //System.out.println("--------------------------------- notify antes ----------------------");
        for (List<String> Lorder : sourceList) {
            //System.out.println("paso a uno nuevo");
            for (String order : Lorder) {
                //System.out.println(order);
            } 
        }
        
        List<List<Order>> mainList = new ArrayList<>();
        String email = sourceList.get(0).get(4);
        List<Order> orders = new ArrayList<>();
        for (List<String> list : sourceList) {
            Order o = new Order();
            o.setName(list.get(0));
            o.setQuantity(Float.parseFloat(list.get(2)));
            o.setSupplierEmail(list.get(4));
            if(!o.getSupplierEmail().equals(email)) {
                mainList.add(orders);
                orders = new ArrayList<>();
                email = o.getSupplierEmail();
            }
            orders.add(o);
        }
        if (!orders.isEmpty())
        {
            mainList.add(orders);
        }
        //System.out.println("--------------------------------- supply----------------------");
        //System.out.println(" ");
        for (List<Order> Lorder : mainList) {
            //System.out.println(Lorder.get(0).getSupplierEmail());
            for (Order order : Lorder) {
                //System.out.println(order.getName());
            } 
        }
        return mainList;
    }

    private MasterPlan addNonWorkinkDay(MasterPlan myMasterPlan, int plan, int pymeId) {
        List<Date> datesNonWorking = nonWorkinkDayFacade.findAllByPyme(pymeId);
        int size = 0;
        List<Order> genericPlan = new ArrayList<>();
        if(plan == 1) {
            size = myMasterPlan.getMyCustomerPlan().getProductionPlanList().size();
            genericPlan = myMasterPlan.getMyCustomerPlan().getProductionPlanList();
        }
        else if(plan == 2) {
            size = myMasterPlan.getMyProductionPlan().getProductionPlanList().size();
            genericPlan = myMasterPlan.getMyProductionPlan().getProductionPlanList();
        }
        else if(plan == 3) {
            size = myMasterPlan.getMySupplyPlan().getSupplyPlanList().size();
            genericPlan = myMasterPlan.getMySupplyPlan().getSupplyPlanList();
        }
        else {
            return null;
        }
        
        Date date = new Date();
        boolean founded = false;
        for (int i = 0; i < genericPlan.size();i++)
        {
            if (genericPlan.get(i).getDate().getDay() == date.getDay() && genericPlan.get(i).getDate().getMonth() == date.getMonth() && genericPlan.get(i).getDate().getYear() ==  date.getYear())
            {
                i = genericPlan.size();
                founded = true;
            }
        }
        if (founded)
        {
            Order neworder = new Order ();
            neworder.setDate(new Date());
            genericPlan.add(0,neworder);
        }
        for (int i = 0; i < size; i++)
        {
            genericPlan = addNonWorkinkDays (i, genericPlan, datesNonWorking);
            
        }
        if (founded)
        {
            genericPlan.remove(0);
        }
        if(plan == 1) {
            myMasterPlan.getMyCustomerPlan().setProductionPlanList(genericPlan);
        }
        else if(plan == 2) {
            myMasterPlan.getMyProductionPlan().setProductionPlanList(genericPlan);
        }
        else if(plan == 3) {
            myMasterPlan.getMySupplyPlan().setSupplyPlanList(genericPlan);
        }
        return myMasterPlan;
    }

    private List<Order> addNonWorkinkDays(int i, List<Order> productionPlan, List<Date> datesNonWorking) {
        
        Date currentDate = productionPlan.get(i).getDate();
        int cantidad = 0;
        for(int j  = 0; j < datesNonWorking.size(); j++) {
            Date date = datesNonWorking.get(j);
            ////System.out.println("current: " + currentDate + "   date: " + date);
            if (date.getDay() == currentDate.getDay() && date.getMonth() == currentDate.getMonth() && date.getYear() == currentDate.getYear())
            {
                cantidad++;
                //System.out.println("fecha antigua ----------------- " + currentDate);
                currentDate = addDaysToDate(currentDate, 1);
                productionPlan.get(i).setDate(currentDate);
                j = -1; 
                //System.out.println("cambio de fecha ----------------- " + currentDate);
            }
        }
        if (cantidad != 0)
        {
            for (int k =  (i + 1); k < productionPlan.size(); k++)
            {
                currentDate = addDaysToDate(productionPlan.get(k).getDate(), cantidad);
                productionPlan.get(k).setDate(currentDate);
            }
        }
        return productionPlan;
    }

    @Override
    public List<List<String>> caculateProductionBatches(List<List<String>> productionRequest) {
        List<List<String>> request = new ArrayList<>();
        for (List<String> list : productionRequest) {
           Product product = productFacade.find(Integer.parseInt(list.get(0)));
           double cantProduct = Double.parseDouble(list.get(1));
           double capacity = product.getCapacity();
           double batches = cantProduct / capacity;
           if (cantProduct % capacity == 0)
           {
               for (int i = 1; i <= batches; i++)
               {
                   List<String> newOrder = new ArrayList<>();
                   newOrder.add("" + product.getIdproduct());
                   newOrder.add("" + product.getName());
                   newOrder.add("" + i);
                   newOrder.add("" + capacity);
                   newOrder.add("" + capacity);
                   request.add(newOrder);
               }
           }
           else {
               int intBatches = (int)batches;
               for (int i = 1; i <= intBatches; i++)
               {
                   List<String> newOrder = new ArrayList<>();
                   newOrder.add("" + product.getIdproduct());
                   newOrder.add("" + product.getName());
                   newOrder.add("" + i);
                   newOrder.add("" + capacity);
                   newOrder.add("" + capacity);
                   request.add(newOrder);
               }
               double residuo = cantProduct % capacity;
               List<String> newOrder = new ArrayList<>();
               newOrder.add("" + product.getIdproduct());
               newOrder.add("" + product.getName());
               newOrder.add("" + (intBatches + 1));
               newOrder.add("" + residuo);
               newOrder.add("" + capacity);
               request.add(newOrder);
           }
        }
        
        return request;
    }
}
